import pandas as pd
import numpy as np

def fill_missing_or_zero(data, fill_method='mean', fill_value=None, columns=None):
    """
    填充数据中的缺失值(NaN)和零值
    
    参数:
        data (pd.DataFrame 或 pd.Series): 要处理的数据
        fill_method (str): 填充方法，可选值：'mean'（均值）、'median'（中位数）、
                          'mode'（众数）、'zero'（0）、'value'（指定值）
        fill_value: 当fill_method为'value'时的填充值，其他方法忽略
        columns (list): 指定需要处理的列，默认处理所有列
    
    返回:
        pd.DataFrame 或 pd.Series: 填充后的结果
    """
    # 复制数据避免修改原数据
    data_copy = data.copy()
    
    # 确定需要处理的列
    if columns is None:
        if isinstance(data_copy, pd.DataFrame):
            columns = data_copy.columns
        else:  # Series
            columns = [data_copy.name]
    
    for col in columns:
        # 检查该列是否存在
        if col not in data_copy.columns and isinstance(data_copy, pd.DataFrame):
            continue
        
        # 获取当前列数据
        if isinstance(data_copy, pd.DataFrame):
            col_data = data_copy[col]
        else:
            col_data = data_copy
        
        # 找到需要填充的位置（缺失值或零值）
        mask = col_data.isna() | (col_data == 0)
        
        if mask.sum() == 0:
            continue  # 没有需要填充的值
        
        # 根据填充方法计算填充值
        if fill_method == 'mean':
            # 排除零值和缺失值计算均值
            fill_val = col_data.replace(0, np.nan).mean(skipna=True)
        elif fill_method == 'median':
            fill_val = col_data.replace(0, np.nan).median(skipna=True)
        elif fill_method == 'mode':
            # 众数可能有多个，取第一个
            mode_vals = col_data.replace(0, np.nan).mode(dropna=True)
            fill_val = mode_vals.iloc[0] if not mode_vals.empty else 0
        elif fill_method == 'zero':
            fill_val = 0
        elif fill_method == 'value':
            if fill_value is None:
                raise ValueError("使用'value'方法时必须指定fill_value")
            fill_val = fill_value
        else:
            raise ValueError("不支持的填充方法，请使用'mean'、'median'、'mode'、'zero'或'value'")
        
        # 执行填充
        if isinstance(data_copy, pd.DataFrame):
            data_copy.loc[mask, col] = fill_val
        else:
            data_copy.loc[mask] = fill_val
    
    return data_copy